package com.fszs.common.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fszs.common.exception.ServiceException;
import java.util.Date;

/**
 * 数据校验util
 * @author panmanyuan
 **/
public class RequireUtil {


    /**
     * 抛出一条异常
     * @param msg 提示语
     * @author panmanyuan
     **/
    public static void exception(String msg) {
        throw new ServiceException(msg);
    }

    /**
     * 必须不能是 null 否则抛出异常
     * @param msg 提示语
     * @param obj 要校验的数据
     * @author panmanyuan
     **/
    public static void notNull(String msg, Object obj) {
        if (ObjectUtil.isNull(obj)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 必须都不能是 null 否则抛出异常
     * @param msg 提示语
     * @param objs 要校验的数据
     * @author panmanyuan
     **/
    public static void allNotNull(String msg, Object... objs) {
        if (ObjectUtil.hasNull(objs)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 不能所有都是null (至少有一个非null) 否则抛出异常
     * @param msg 提示语
     * @param objs 要校验的数据
     * @author panmanyuan
     **/
    public static void notAllNull(String msg, Object... objs) {
        for (Object obj : objs) {
            if (ObjectUtil.isNotNull(obj)) {
                return;
            }
        }
        RequireUtil.exception(msg);
    }

    /**
     * 必须不能是null并且不能是 "" 否则抛出异常 (为字符串时不会去除前后空格)<br>
     * 支持 String/StringBuilder/StringBuffer/Map/List 等常用数据结构<br>
     * 为String/StringBuilder/StringBuffer类型时 包含 "" 校验<br>
     * 为Map/List等类型时 包含 size() > 0 校验
     * @param obj 要校验的数据
     * @param msg 提示语
     * @author panmanyuan
     **/
    public static void notEmpty(String msg, Object obj) {
        if (ObjectUtil.isEmpty(obj)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 必须都不能是null并且不能是 "" 否则抛出异常 (为字符串时不会去除前后空格)<br>
     * 支持 String/StringBuilder/StringBuffer/Map/List 等常用数据结构<br>
     * 为String/StringBuilder/StringBuffer类型时 包含 "" 校验<br>
     * 为Map/List等类型时 包含 size() > 0 校验
     * @param obj 要校验的数据
     * @param msg 提示语
     * @author panmanyuan
     **/
    public static void allNotEmpty(String msg, Object... obj) {
        if (ObjectUtil.hasEmpty(obj)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 不能都是empty 否则抛出异常 (为字符串时不会去除前后空格)<br>
     * 支持 String/StringBuilder/StringBuffer/Map/List 等常用数据结构<br>
     * 为String/StringBuilder/StringBuffer类型时 包含 "" 校验<br>
     * 为Map/List等类型时 包含 size() > 0 校验
     * @param obj 要校验的数据
     * @param msg 提示语
     * @author panmanyuan
     **/
    public static void notAllEmpty(String msg, Object... obj) {
        if (ObjectUtil.isAllEmpty(obj)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 必须不能是null 并且去除前后空格后不能是 "" 否则抛出异常
     * @param msg 提示语
     * @param obj 要校验的数据
     * @author panmanyuan
     **/
    public static void notBlank(String msg, CharSequence obj) {
        if (StrUtil.isBlank(obj)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 必须都不能是null 并且去除前后空格后不能是 "", 有任意一个不符合则抛出异常
     * @param msg 提示语
     * @param obj 要校验的数据
     * @author panmanyuan
     **/
    public static void allNotBlank(String msg, CharSequence... obj) {
        if (StrUtil.hasBlank(obj)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 不能都是 blank 有任意一个不符合则抛出异常
     * @param msg 提示语
     * @param obj 要校验的数据
     * @author panmanyuan
     **/
    public static void notAllBlank(String msg, CharSequence... obj) {
        if (StrUtil.isAllBlank(obj)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 必须不能相等, 否则抛出异常
     * @param msg 提示语
     * @param obj1 obj1
     * @param obj2 obj2
     * @author panmanyuan
     **/
    public static void notEquals(String msg, Object obj1, Object obj2) {
        if (ObjectUtil.equal(obj1, obj2)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * obj不能是null 并且 objs中必须有至少一个元素于 obj 相等, 否则抛出异常
     * @param msg 提示语
     * @param obj obj
     * @param objs 多个obj/obj数组
     * @author panmanyuan
     **/
    public static void anyIsEquals(String msg, Object obj, Object... objs) {
        // 此处判断非null, 是因为对程序而言两个null值相等是无意义的
        RequireUtil.notNull(msg, obj);
        for (Object obj1 : objs) {
            if (ObjectUtil.equal(obj1, obj)) {
                return;
            }
        }
        RequireUtil.exception(msg);
    }

    /**
     * 必须不是null 并且相等, 否则抛出异常
     * @param msg 提示语
     * @param obj1 obj1
     * @param obj2 obj2
     * @author panmanyuan
     **/
    public static void isEquals(String msg, Object obj1, Object obj2) {
        // 此处判断非null, 是因为对程序而言两个null值相等是无意义的
        RequireUtil.notNull(msg, obj1);
        if (!obj1.equals(obj2)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 字符串必须json字符串 (包含 json对象 和 json数组) 否则抛出异常
     * @param msg 提示语
     * @param jsonStr 要校验的数据
     * @author panmanyuan
     **/
    public static void isJson(String msg, String jsonStr) {
        if (!JSONUtil.isJson(jsonStr)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 字符串必须是json对象 否则抛出异常
     * @param msg 提示语
     * @param jsonStr 要校验的数据
     * @author panmanyuan
     **/
    public static void isJsonObj(String msg, String jsonStr) {
        if (!JSONUtil.isJsonObj(jsonStr)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 字符串必须是json数组 否抛出异常
     * @param msg 提示语
     * @param jsonStr 要校验的数据
     * @author panmanyuan
     **/
    public static void isJsonArray(String msg, String jsonStr) {
        if (!JSONUtil.isJsonArray(jsonStr)) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * num 不能大于 max 否则抛出异常
     * @param msg 提示语
     * @param num 实际数值
     * @param max 最大上限
     * @author panmanyuan
     **/
    public static void notGreater(String msg, int num, int max) {
        if (num > max) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * num 不能大于或等于 max 否则抛出异常
     * @param msg 提示语
     * @param num 实际数值
     * @param max 最大上限
     * @author panmanyuan
     **/
    public static void notGreaterOrEquals(String msg, int num, int max) {
        if (num >= max) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * num 不能小于 min 否则抛出异常
     * @param msg 提示语
     * @param num 实际数值
     * @param min 最小下限
     * @author panmanyuan
     **/
    public static void notLess(String msg, int num, int min) {
        if (num < min) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * num 不能小于或等于 min 否则抛出异常
     * @param msg 提示语
     * @param num 实际数值
     * @param min 最小下限
     * @author panmanyuan
     **/
    public static void notLessOrEqulas(String msg, int num, int min) {
        if (num <= min) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * date1 必须早于 date2 否则(包含等于)抛出异常
     * @param msg 提示语
     * @param date1 date1
     * @param date2 date2
     * @author panmanyuan
     **/
    public static void isBefore(String msg, Date date1, Date date2) {
        if (DateUtil.compare(date1, date2) >= 0) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * date1 必须早于或等于 date2 否则抛出异常
     * @param msg 提示语
     * @param date1 date1
     * @param date2 date2
     * @author panmanyuan
     **/
    public static void isBeforeOrEquals(String msg, Date date1, Date date2) {
        if (DateUtil.compare(date1, date2) > 0) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * 表达式 bool 必须是 true, 否则抛出异常
     * @param msg 提示语
     * @param bool 表达式
     * @author panmanyuan
     **/
    public static void isTrue(String msg, boolean bool) {
        if (!bool) {
            RequireUtil.exception(msg);
        }
    }

    /**
     * bools 必须全部是 true, 否则抛出异常
     * @param msg 提示语
     * @param bools 多个表达式/表达式数组
     * @author panmanyuan
     **/
    public static void allIsTrue(String msg, boolean... bools) {
        for (boolean bool : bools) {
            if (!bool) {
                RequireUtil.exception(msg);
            }
        }
    }

    /**
     * bools 至少一个是 true, 否则抛出异常
     * @param msg 提示语
     * @param bools 多个表达式/表达式数组
     * @author panmanyuan
     **/
    public static void anyIsTrue(String msg, boolean... bools) {
        for (boolean bool : bools) {
            if (bool) {
                return;
            }
        }
        RequireUtil.exception(msg);
    }

    /**
     * 表达式 bool 必须是 false, 否则抛出异常
     * @param msg 提示语
     * @param bool 表达式
     * @author panmanyuan
     **/
    public static void isFalse(String msg, boolean bool) {
        if (bool) {
            RequireUtil.exception(msg);
        }
    }


}
